﻿#include <iostream>

#include "Shape.h"
using namespace std;

int main()
{
    assert(CSerialiableFactory::Instance().CreatorCount() == 4);
    if (CSerialiableFactory::Instance().CreatorCount() != 4)
    {
        cout << "unused symbols removed." << endl;
    }
    
    auto circle = std::shared_ptr<Circle>(new Circle());
    auto rect = std::shared_ptr<Rectangle>(new Rectangle());
    auto group = ShapeGroup();

    group.Add(circle);
    group.Add(circle);
    group.Add(rect);
    group.Add(nullptr);

    group.Draw();

    {
        COutputSerializer ser(std::string("a.data"), std::endian::big);
        ser << group;
    }

    {
        CInputSerializer ser(std::string("a.data"));
        std::shared_ptr<ISerializable> readItem;
        ser >> readItem;

        auto groupRead = std::dynamic_pointer_cast<ShapeGroup>(readItem);
        assert(groupRead);
        assert(groupRead->m_shapes.size() == group.m_shapes.size());
        assert(groupRead->m_shapes[0] == groupRead->m_shapes[1]);
        assert(groupRead->m_shapes[3] == nullptr);

        groupRead->Draw();
    }

    Header header;
    {
        header.version = 99;
        COHSerializer<Header> ser(std::string("b.data"), header);
        ser << group;
    }

    {
        Header header;
        CIHSerializer<Header> ser(std::string("b.data"), header);
        std::shared_ptr<ISerializable> readItem;
        ser >> readItem;

        auto groupRead = std::dynamic_pointer_cast<ShapeGroup>(readItem);
        assert(groupRead);
        assert(groupRead->m_shapes.size() == group.m_shapes.size());
        assert(groupRead->m_shapes[0] == groupRead->m_shapes[1]);

        groupRead->Draw();
    }

    {
        std::vector<uint64_t> v{ 1, 2, 3};
        {
            COutputSerializer ser(std::wstring(L"c.data"), std::endian::native);
            ser << v;
        }
        std::vector<uint64_t> v1;
        {
            CInputSerializer ser(std::wstring(L"c.data"));
            ser >> v1;
        }

        assert(v1.size() == v.size());
        assert(v1[0] == v[0] && v1[1] == v[1] && v1[2] == v[2]);
    }

    return 0;
}
